<!DOCTYPE html>
<html>
<head>
<title>Spring-Mass System</title>
</head>
<body>
<canvas id="physicsCanvas" width="400" height="500"></canvas>
<script>
const canvas = document.getElementById('physicsCanvas');
const ctx = canvas.getContext('2d');

// Style settings
ctx.lineWidth = 2;
ctx.strokeStyle = 'black';
ctx.fillStyle = 'black';
ctx.font = 'italic 20px Arial';

// Center of drawing
const cx = canvas.width / 2;

// 1. Draw Ceiling
const ceilingY = 50;
ctx.beginPath();
ctx.moveTo(cx - 100, ceilingY);
ctx.lineTo(cx + 100, ceilingY);
ctx.stroke();

// Hatching for ceiling
ctx.save();
ctx.lineWidth = 1.5;
for (let i = -100; i < 100; i += 10) {
    ctx.beginPath();
    ctx.moveTo(cx + i, ceilingY);
    ctx.lineTo(cx + i - 10, ceilingY - 10);
    ctx.stroke();
}
ctx.restore();

// 2. Draw Spring
const springStartY = ceilingY;
const springTopRodY = springStartY + 20;
const springCoilStartY = springTopRodY;
const numCoils = 8;
const coilRadius = 15;
const coilLength = 80;
const springCoilEndY = springCoilStartY + coilLength;

// Top rod of spring
ctx.beginPath();
ctx.moveTo(cx, springStartY);
ctx.lineTo(cx, springTopRodY);
ctx.stroke();

// Spring coils
ctx.beginPath();
ctx.moveTo(cx, springCoilStartY);
const totalPoints = numCoils * 20;
for (let i = 0; i <= totalPoints; i++) {
    const angle = (i / totalPoints) * numCoils * 2 * Math.PI;
    const px = cx + coilRadius * Math.sin(angle);
    const py = springCoilStartY + (i / totalPoints) * coilLength;
    ctx.lineTo(px, py);
}
ctx.stroke();

// Spring label 'k'
ctx.fillText('k', cx + coilRadius + 15, springCoilStartY + coilLength / 2);

// 3. Draw Pan Holder (Basket)
const holderStartY = springCoilEndY;
const holderRodLength = 15;
const holderSplitY = holderStartY + holderRodLength;
const holderBottomY = holderSplitY + 100;
const holderWidthBottom = 70;

// Rod from spring
ctx.beginPath();
ctx.moveTo(cx, holderStartY);
ctx.lineTo(cx, holderSplitY);
ctx.stroke();

// Y-split to cone sides
ctx.beginPath();
ctx.moveTo(cx, holderSplitY);
ctx.lineTo(cx - holderWidthBottom / 2, holderBottomY);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(cx, holderSplitY);
ctx.lineTo(cx + holderWidthBottom / 2, holderBottomY);
ctx.stroke();


// Pan base (m')
const panRadiusX = holderWidthBottom / 2;
const panRadiusY = 10;
ctx.beginPath();
ctx.ellipse(cx, holderBottomY, panRadiusX, panRadiusY, 0, 0, 2 * Math.PI);
ctx.stroke();

// Pan label 'm''
ctx.fillText("m'", cx + panRadiusX + 10, holderBottomY + 5);

// 4. Draw Sphere (m)
const sphereRadius = 12;
const sphereY = holderSplitY + 40;
const sphereX = cx;

// Sphere
ctx.beginPath();
ctx.arc(sphereX, sphereY, sphereRadius, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();

// Sphere highlight
ctx.beginPath();
ctx.arc(sphereX - 4, sphereY - 4, 3, 0, Math.PI * 2);
ctx.fillStyle = 'white';
ctx.fill();

// Redraw sphere outline to be clean after fill
ctx.beginPath();
ctx.arc(sphereX, sphereY, sphereRadius, 0, 2 * Math.PI);
ctx.stroke();

// Sphere label 'm'
ctx.fillStyle = 'black';
const mLabelX = sphereX + sphereRadius + 15;
const mLabelY = sphereY + 15;
ctx.fillText('m', mLabelX, mLabelY);

// The three lines below the label 'm'
ctx.save();
ctx.lineWidth = 1;
ctx.beginPath();
let mCharWidth = ctx.measureText('m').width;
ctx.moveTo(mLabelX + mCharWidth/2 - 5, mLabelY + 5); ctx.lineTo(mLabelX + mCharWidth/2 - 5, mLabelY + 10);
ctx.moveTo(mLabelX + mCharWidth/2, mLabelY + 5); ctx.lineTo(mLabelX + mCharWidth/2, mLabelY + 10);
ctx.moveTo(mLabelX + mCharWidth/2 + 5, mLabelY + 5); ctx.lineTo(mLabelX + mCharWidth/2 + 5, mLabelY + 10);
ctx.stroke();
ctx.restore();


// 5. Draw Height Indicator (h)
const h_indicator_x = cx - 80;
const h_top_y = sphereY;
const h_bottom_y = holderBottomY;

// T-bar top
ctx.beginPath();
ctx.moveTo(h_indicator_x - 10, h_top_y);
ctx.lineTo(h_indicator_x + 10, h_top_y);
ctx.stroke();
// T-bar bottom
ctx.beginPath();
ctx.moveTo(h_indicator_x - 10, h_bottom_y);
ctx.lineTo(h_indicator_x + 10, h_bottom_y);
ctx.stroke();

// Vertical line with arrows
ctx.beginPath();
ctx.moveTo(h_indicator_x, h_top_y);
ctx.lineTo(h_indicator_x, h_bottom_y);
// Top arrow
ctx.moveTo(h_indicator_x - 5, h_top_y + 5);
ctx.lineTo(h_indicator_x, h_top_y);
ctx.lineTo(h_indicator_x + 5, h_top_y + 5);
// Bottom arrow
ctx.moveTo(h_indicator_x - 5, h_bottom_y - 5);
ctx.lineTo(h_indicator_x, h_bottom_y);
ctx.lineTo(h_indicator_x + 5, h_bottom_y - 5);
ctx.stroke();

// Label 'h'
ctx.fillText('h', h_indicator_x - 25, (h_top_y + h_bottom_y) / 2 + 5);


// 6. Draw Bottom Text
ctx.font = '24px "Microsoft YaHei", "SimHei", Arial'; // non-italic for Chinese text
ctx.fillText('习 题  10-7  图', cx - 80, canvas.height - 30);

</script>
</body>
</html>